"""
python基本数据类型：
"""

"""
1、
    python中的变量不需要声明。每个变量在使用前都必须赋值，变量赋值以后该变量才会被创建。
    在 python 中，变量就是变量，它没有类型，我们所说的 ”类型“ 是指变量所指的内存中对象类型
    一个变量可以通过赋值指向不同类型的对象
"""
# 整型变量
a = 1
# 浮点型变量
b = 1.5
# 字符串
c = "hello"
print(a, type(a))
print(b, type(b))
print(c, type(c))

"""
2、多个变量的赋值
"""
num1 = num2 = num3 = 1
print(num1, num2, num3)
n1, n2, s = 1, 2, "abc"
print(n1, n2, s)

"""
3、标准数据类型
    Python3 中常见的数据类型有：
        Number（数字）
        String（字符串）
        bool（布尔类型）
        List（列表）
        Tuple（元组）
        Set（集合）
        Dictionary（字典）
    Python3 的六个标准数据类型中：
        不可变数据（3 个）：Number（数字）、String（字符串）、Tuple（元组）
        可变数据（3 个）：List（列表）、Dictionary（字典）、Set（集合）
    
    Number（数字）：
        Python3 支持 int、float、bool、complex（复数）
        内置的 type() 函数可以用来查询变量所指的对象类型
        
    isinstance：判断变量里面存储的内容是否是对应类型
    
    isinstance 和 type 的区别在于：
        type()不会认为子类是一种父类类型
        isinstance()会认为子类是一种父类类型
        
    数值的运算：+、 -、 *、 /（除法得到一个浮点数）、 //（除法得到一个整数）、 % 、**（乘方）   
"""
a1, a2, a3, a4 = 1, 2.3, True, 4+3j
print(a1, type(a1))
print(a2, type(a2))
print(a3, type(a3))
print(a4, type(a4))

print(isinstance(a, int))  # 判断 a 是不是 int 类型

print(3 / 2)

"""
4、String字符串
    Python中的字符串用单引号 ' 或双引号 " 括起来，同时使用反斜杠 \ 转义特殊字符
    字符串的截取的语法格式如下：变量[头下标:尾下标]  注意：（截取的时候尾下标截取不到）
    索引值以 0 为开始值，-1 为从末尾的开始位置  例如：Hello (从前面索引：0 1 2 3 4，从后面索引：-1 -2 -3 -4 -5)
    +（加号）：字符串的连接符
    *（星号）：复制当前字符串，与之结合的数字为复制的次数
    Python 使用反斜杠 \ 转义特殊字符，如果你不想让反斜杠发生转义，可以在字符串前面添加一个 r，表示原始字符串
    Python 没有单独的字符类型，一个字符就是长度为1的字符串
    Python 字符串不能被改变。向一个索引位置赋值，比如 word[0] = 'm' 会导致错误
"""
str1 = "Hello world"
print(str1)  # 打印字符串 str1
print(str1[1])  # 字符串索引，打印字符串中第 2 的字符
print(str1[0:-1])  # 字符串截取，打印字符串第 1 个到倒数第 2 个字符（不包含倒数第一个字符）
print(str1[:-1])  # 头下标不写，代表从一个字符开始打印。
print(str1[0:])  # 尾下标不写，代表打印到最后一个字符（包含最后一个）
print(str1[:])  # 从开头打印到结尾
print(str1 * 2)  # 打印字符串 2 次
print(str1 + "TEST")  # 打印字符串和 “TEST” 拼接在一起

print("Ru\noob")
print(r"Ru\noob")

"""
5、bool(布尔类型)
    布尔类型：True 和 False
    布尔类型可以和其他数据类型进行比较，比如数字、字符串等。在比较时，Python 会将 True 视为 1，False 视为 0
    布尔类型也可以被转换成其他数据类型，比如整数、浮点数和字符串。在转换时，True 会被转换成 1，False 会被转换成 0
    在 Python 中，所有非零的数字和非空的字符串、列表、元组等数据类型都被视为 True，只有 0、空字符串、空列表、空元组等被视为 False
"""
# 布尔类型的整数表现
b1 = True
b2 = False
print("n1的类型:", type(b1), "n2的类型:", type(b2))
# 布尔类型的整数表现
print(int(True))
print(int(False))
# 使用 bool() 函数进行转换
print(bool(10))  # True
print(bool(-1))  # True
print(bool(0))   # False
print(bool(""))  # False
print(bool(" "))  # True
print(bool("ab"))  # True
print(bool([]))  # False
print(bool([1, 2]))  # True
# 布尔逻辑运算
print(True and False)
print(True or False)
print(not True)
print(not False)
# 布尔比较运算
print(3 > 1)
print(2 != 2)
print(6 == 6)
print(1 > 3)
# 布尔值在控制流中的应用
if True:
    print("This will always print")
if not False:
    print("This will always print")
b3 = 10
if b3:
    print("if b3 is not zero ,this is print")

"""
6、List（列表）
    列表中元素的类型可以不相同，它支持数字，字符串甚至可以包含列表（所谓嵌套）
    列表是写在方括号 [] 之间、用逗号分隔开的元素列表
    和字符串一样，列表同样可以被索引和截取，列表被截取后返回一个包含所需元素的新列表
    String VS List: String里面的元素不能修改，List里面的元素可修改
"""
list1 = [1, "abc", 1.5, 3, 6]  # 列表
list2 = ["hello", "hi"]
print(list1[0])  # 列表的索引，打印链表中下标为 0 的元素
print(list1[1:3])  # 列表的截取，打印列表中下标为 1~3 的所有元素（不包含3）
print(list1[1:])  # 列表的截取，从下标 1 截取到最后一个元素（包含最后一个）
print(list1[:])  # 列表的截取，从开始打印到结束
print(list2 * 2)  # 打印列表两次
print(list1 + list2)  # 链表的拼接

list1[0] = 10  # 列表元素的修改
print(list1)  # 打印列表

print(list1[::2])  # 列表的截取，指定步长，从左边开始
print(list1[::-2])  # 列表的截取，指定步长，从右边开始

"""
7、Tuple（元组）
    元组（tuple）与列表类似，不同之处在于元组的元素不能修改。元组写在小括号 () 里，元素之间用逗号隔开。元组中的元素类型也可以不相同。
    元组与字符串类似，可以被索引且下标索引从0开始，-1 为从末尾开始的位置。也可以进行截取
    虽然tuple的元素不可改变，但它可以包含可变的对象，比如list列表
    如果你想创建只有一个元素的元组，需要注意在元素后面添加一个逗号，以区分它是一个元组而不是一个普通的值，这是因为在没有逗号的情况下，Python会将括号解释为数学运算中的括号，而不是元组的表示
    按存放的顺序进行存储的
"""
tup1 = (1)  # 只有一个元素，不加逗号。会将其当作一个数学运算中的括号
print(type(tup1))
tup2 = (1,)
print(type(tup2))
tup3 = (1, 2, "abc", 3, "hello")
print(tup3[1:3])  # 元组的截取
print(tup3 * 2)  # 元组的重复
print(tup3[1])  # 元组的索引

"""
8、Set（集合）
    Python 中的集合（Set）是一种无序、可变的数据类型，用于存储唯一的元素。
    集合中的元素不会重复，并且可以进行交集、并集、差集等常见的集合操作。
    在 Python 中，集合使用大括号 {} 表示，元素之间用逗号 , 分隔。
    另外，也可以使用 set() 函数创建集合。
    注意：创建一个空集合必须用 set() 而不是 { }，因为 { } 是用来创建一个空字典。
"""

set1 = set()  # 创建一个空集合
print(type(set1))
set2 = {"a", "b", "c", "d", "e"}
set3 = {"a", "f", "g"}
print(set2)   # 输出集合，重复的元素被自动去掉
if "a" in set2:
    print("yes")
else:
    print("no")
# set 可以进行集合运算
print(set2 ^ set3)  # 不同存在的元素
print(set2 - set3)  # 差集
print(set2 | set3)  # 并集
print(set2 & set3)  # 交集

"""
9、Dictionary（字典）
    列表是有序的对象集合，字典是无序的对象集合。两者之间的区别在于：字典当中的元素是通过键来存取的，而不是通过偏移存取。
    字典是一种映射类型，字典用 { } 标识，它是一个无序的 键(key) : 值(value) 的集合。
    键(key)必须使用不可变类型。
    在同一个字典中，键(key)必须是唯一的。
"""

dict1 = {"a":1, "b":2, "c":3}
print(dict1)
print(type(dict1))
print(dict1["a"])  # 输出键为 a 的值
print(dict1.keys())  # 打印所有的键
print(dict1.values())  # 打印所有的值

"""
10、bytes 类型
    在 Python3 中，bytes 类型表示的是不可变的二进制序列（byte sequence）。
    与字符串类型不同的是，bytes 类型中的元素是整数值（0 到 255 之间的整数），而不是 Unicode 字符。
    bytes 类型通常用于处理二进制数据，比如图像文件、音频文件、视频文件等等。在网络编程中，也经常使用 bytes 类型来传输二进制数据。
    创建 bytes 对象的方式有多种，最常见的方式是使用 b 前缀。此外，也可以使用 bytes() 函数将其他类型的对象转换为 bytes 类型。bytes() 函数的第一个参数是要转换的对象，第二个参数是编码方式，如果省略第二个参数，则默认使用 UTF-8 编码
    与字符串类型类似，bytes 类型也支持许多操作和方法，如切片、拼接、查找、替换等等。同时，由于 bytes 类型是不可变的，因此在进行修改操作时需要创建一个新的 bytes 对象。
    bytes 类型中的元素是整数值，因此在进行比较操作时需要使用相应的整数值。
"""

byte1 = b"hello"  # 创建一个bytes类型
byte2 = bytes("hi", encoding="utf-8")
print(byte1, type(byte1))
print(byte2, type(byte2))
